
#include "type.h"
#include "blink_config.h"

#ifndef BLINK_NUM_MAX
#error "BLINK_NUM_MAX NOT HAVE A CONFIG VALUE"
#endif

#define BLINK_STATE_OFF		BLINK_OFF_STATE_DEFINE
#define BLINK_STATE_ON		(!BLINK_OFF_STATE_DEFINE)

typedef struct {
	uint16_t period;
	uint16_t duty_ration;
	uint16_t count;
	uint8_t blink_times;
	uint8_t state;
	uint8_t finish_state;
} BLINK_STRUCT;

static BLINK_STRUCT BLINKS[BLINK_NUM_MAX];

void blink_on(uint16_t blink_num)
{
	if(blink_num < BLINK_NUM_MAX){
		blink_set_on_config(blink_num);
	    BLINKS[blink_num].state = BLINK_STATE_ON;
	}
}

void blink_off(uint16_t blink_num)
{
	if(blink_num < BLINK_NUM_MAX){
		blink_set_off_config(blink_num);
	    BLINKS[blink_num].state = BLINK_STATE_OFF;
	}
}

void blink_toggle(uint16_t blink_num)
{
	if(blink_num < BLINK_NUM_MAX){
		if(BLINKS[blink_num].state == BLINK_STATE_ON){
			blink_off(blink_num);
		}
		else{
			blink_on(blink_num);
		}
	}
}

uint8_t blink_get_state(uint16_t blink_num)
{
	if(blink_num < BLINK_NUM_MAX){
    	return BLINKS[blink_num].state;
	}
	else{
		return BLINK_STATE_OFF;
	}
}

void blink_set(uint16_t blink_num, 
				uint16_t set_period, uint16_t set_duty_ration)
{
	if(set_duty_ration > set_period){
		return;
	}

	if(blink_num < BLINK_NUM_MAX){
		BLINKS[blink_num].period = set_period;
		BLINKS[blink_num].duty_ration = set_duty_ration;
	}
}

void blink_stop(uint16_t blink_num)
{
	if(blink_num < BLINK_NUM_MAX){
		BLINKS[blink_num].blink_times = 0;
	}
}

//blink_times = 0xff blink forever
void blink_start(uint16_t blink_num, 
				uint8_t set_blink_times, uint8_t set_finish_state)
{
	if(set_blink_times == 0){
		return;
	}
	
	if(blink_num < BLINK_NUM_MAX){
		// if(BLINKS[blink_num].state] == BLINK_STATE_ON){
		// 	blink_off(temp);
		// 	BLINKS[blink_num].count] = set_duty_ration;
		// }
		// else{
			blink_on(blink_num);
			BLINKS[blink_num].count = 0;
		// }
		BLINKS[blink_num].blink_times = set_blink_times;
		BLINKS[blink_num].finish_state = set_finish_state;
	}
}

uint8_t blink_is_blink(uint16_t blink_num)
{
	if(blink_num < BLINK_NUM_MAX){
		return (BLINKS[blink_num].blink_times == 0)?0:1;
	}
	else{
		return 0;
	}
}

uint8_t blink_check_blink_all(void)
{
	volatile uint8_t i;
    for(i = 0; i < BLINK_NUM_MAX; i++) {
		if(BLINKS[i].blink_times != 0){
			return 1;
		}
	}
	return 0;
}


void blink_init(void) 
{
	volatile uint8_t i;
    for(i = 0; i < BLINK_NUM_MAX; i++) {
        BLINKS[i].period = 0;
        BLINKS[i].duty_ration = 0;
        BLINKS[i].count = 0;
		BLINKS[i].blink_times = 0;
        BLINKS[i].state = BLINK_STATE_OFF;
        BLINKS[i].finish_state = BLINK_STATE_OFF;
		blink_off(i);
	}
}

void blink_handler(void)
{
	volatile uint8_t i;
	for (i = 0; i < BLINK_NUM_MAX; i++) {
        if(BLINKS[i].blink_times == 0){
            continue;
        }

		if(BLINKS[i].count == 0){
			blink_on(i);
		}

		if(BLINKS[i].count == BLINKS[i].duty_ration){
			blink_off(i);
			if(BLINKS[i].blink_times != 0xff){
				BLINKS[i].blink_times--;
			}
		}

		if(BLINKS[i].count >= BLINKS[i].period - 1){
			BLINKS[i].count = 0;
		}
		else{
			BLINKS[i].count++;
		}
		if(BLINKS[i].blink_times == 0){
			BLINKS[i].count = 0;
			if(BLINKS[i].finish_state != BLINK_STATE_OFF){
				blink_on(i);
			}
		}
	}
}

